#pragma once
#include<iostream>
#include<string>
#include"LogMessage.hpp"
#include"C++_pool_thread.hpp"
#include"task.hpp"
#include<functional>
#include<sys/types.h>
#include<sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

class TCP_SERVER{
public:

    TCP_SERVER(uint16_t port)
    :_ip("0.0.0.0"), _port(port), _monitor_sockfd(-1)
    {}

    void init()
    {
        //创建套接字
        _monitor_sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_monitor_sockfd < 0) { logMessage(FATAL, "create socker error"); exit(0);}
        else logMessage(NORMAL, "create socker success");

        //绑定端口
        struct sockaddr_in to_client;
        to_client.sin_family = AF_INET;
        to_client.sin_port = htons(_port);
        to_client.sin_addr.s_addr = inet_addr(_ip.c_str());
        socklen_t len = sizeof(to_client);

        int check_bind = bind(_monitor_sockfd, (struct sockaddr*)&to_client, len);
        if (check_bind == -1) {logMessage(FATAL, "bind socket error"); exit(0);}
        else logMessage(NORMAL, "bind socket success");

        //设置监听套接字，该套接字仅用于监听连接
        int check_listen = listen(_monitor_sockfd, 5);
        if (check_listen == -1) {logMessage(FATAL, "listen error"); exit(0);}
        else logMessage(NORMAL, "listen success");

    }

    void start()
    {
        thread_pool<task> deal_task;
        deal_task.run();
        logMessage(NORMAL, "create thread pool success");
        while(true)
        {   
            struct sockaddr_in addr;
            socklen_t len = sizeof(addr);
            int sockfd = accept(_monitor_sockfd, (struct sockaddr*)&addr, &len);

            if (sockfd < 0) {logMessage(ERROR, "get client sockfd error");}
            else logMessage(NORMAL, "get client sockfd success");
            
            deal_task.push(task(sockfd, serverIO));
        }
    }


private:
    std::string _ip;
    uint16_t _port;
    int _monitor_sockfd;
};